package com.and.rsspect;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

/**
 * 
 * RSS读取类
 * 
 * @author che.heng
 *
 */
public class AndroidRSSReader extends AbsRRSReader {

	public static final long serialVersionUID = 2065836206870624879L;

	
	public AndroidRSSReader() {
	}
	@Override
	public RSS readRSS(XmlPullParser reader) throws Exception {

		Channel channel = null;
		List<Attribute> attributes = null;
		List<Extension> extensions = null;

		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_DOCUMENT:
				break;
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("channel")) {
					reader.next();
					channel = readChannel(reader);
				} else if (reader.getName().equals("rss")) {
					attributes = getAttributes(reader);
				} else {
					try {
						extensions = readExtension(reader, extensions,
								reader.getName());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				break;
			case XmlPullParser.END_TAG:
				break;
			}
		}
		return AndroidRSSDoc.buildRSS(channel, attributes, extensions);
	}

	@Override
	protected Channel readChannel(XmlPullParser reader) throws Exception {

		Title title = null;
		Link link = null;
		Description description = null;
		Language language = null;
		Copyright copyright = null;
		ManagingEditor managingEditor = null;
		WebMaster webMaster = null;
		PubDate pubDate = null;
		LastBuildDate lastBuildDate = null;
		List<Category> categories = null;
		Generator generator = null;
		Docs docs = null;
		Cloud cloud = null;
		TTL ttl = null;
		Image image = null;
		Rating rating = null;
		TextInput textInput = null;
		SkipHours skipHours = null;
		SkipDays skipDays = null;
		List<Item> items = null;
		List<Extension> extensions = null;

		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("item")) {
					reader.next();
					if (items == null)
						items = new ArrayList<Item>();
					items.add(readItem(reader));
				} else if (reader.getName().equals("title")) {
					title = readTitle(reader);
				} else if (reader.getName().equals("link")) {
					link = readLink(reader);
				} else if (reader.getName().equals("description")) {
					description = readDescription(reader);
				} else if (reader.getName().equals("language")) {
					language = readLanguage(reader);
				} else if (reader.getName().equals("copyright")) {
					copyright = readCopyright(reader);
				} else if (reader.getName().equals("managingEditor")) {
					managingEditor = readManagingEditor(reader);
				} else if (reader.getName().equals("webMaster")) {
					webMaster = readWebMaster(reader);
				} else if (reader.getName().equals("pubDate")) {
					pubDate = readPubDate(reader);
				} else if (reader.getName().equals("lastBuildDate")) {
					lastBuildDate = readLastBuildDate(reader);
				} else if (reader.getName().equals("category")) {
					categories = readCategory(reader, categories);
				} else if (reader.getName().equals("generator")) {
					generator = readGenerator(reader);
				} else if (reader.getName().equals("docs")) {
					docs = readDocs(reader);
				} else if (reader.getName().equals("cloud")) {
					cloud = readCloud(reader);
				} else if (reader.getName().equals("ttl")) {
					ttl = readTTL(reader);
				} else if (reader.getName().equals("image")) {
					try {
						image = readImage(reader);
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else if (reader.getName().equals("rating")) {
					rating = readRating(reader);
				} else if (reader.getName().equals("textInput")) {
					textInput = readTextInput(reader);
				} else if (reader.getName().equals("skipHours")) {
					skipHours = readSkipHours(reader);
				} else if (reader.getName().equals("skipDays")) {
					skipDays = readSkipDays(reader);
				} else {
					try {
						extensions = readExtension(reader, extensions,
								reader.getName());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				break;
			case XmlPullParser.END_TAG:
				if (reader.getName().equals("channel")) {
					return AndroidRSSDoc.buildChannel(title, link, description,
							language, copyright, managingEditor, webMaster,
							pubDate, lastBuildDate, categories, generator,
							docs, cloud, ttl, image, rating, textInput,
							skipHours, skipDays, extensions, items);
				}
				break;
			}
		}
		return null;
	}

	@Override
	protected List<Item> readItem(XmlPullParser reader, List<Item> items)
			throws Exception {
		if (items == null)
			items = new ArrayList<Item>();
		Title title = null;
		Link link = null;
		Description description = null;
		Author author = null;
		List<Category> categories = null;
		Comments comments = null;
		Enclosure enclosure = null;
		GUID guid = null;
		PubDate pubDate = null;
		Source source = null;
		List<Extension> extensions = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("title")) {
					title = readTitle(reader);
				} else if (reader.getName().equals("link")) {
					link = readLink(reader);
				} else if (reader.getName().equals("description")) {
					description = readDescription(reader);
				} else if (reader.getName().equals("author")) {
					author = readAuthor(reader);
				} else if (reader.getName().equals("category")) {
					categories = readCategory(reader, categories);
				} else if (reader.getName().equals("comments")) {
					comments = readComments(reader);
				} else if (reader.getName().equals("enclosure")) {
					enclosure = readEnclosure(reader);
				} else if (reader.getName().equals("guid")) {
					guid = readGUID(reader);
				} else if (reader.getName().equals("pubDate")) {
					pubDate = readPubDate(reader);
				} else if (reader.getName().equals("source")) {
					source = readSource(reader);
				} else {
					try {
						extensions = readExtension(reader, extensions,
								reader.getName());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				break;
			case XmlPullParser.END_TAG:
				if (reader.getName().equals("item")) {
					items.add(AndroidRSSDoc.buildItem(title, link, description,
							author, categories, comments, enclosure, guid,
							pubDate, source, extensions));
					return items;
				}
				break;
			}
		}

		return null;
	}

	@Override
	protected Item readItem(XmlPullParser reader) throws Exception {

		Title title = null;
		Link link = null;
		Description description = null;
		Author author = null;
		List<Category> categories = null;
		Comments comments = null;
		Enclosure enclosure = null;
		GUID guid = null;
		PubDate pubDate = null;
		Source source = null;
		List<Extension> extensions = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("title")) {
					title = readTitle(reader);
				} else if (reader.getName().equals("link")) {
					link = readLink(reader);
				} else if (reader.getName().equals("description")) {
					description = readDescription(reader);
				} else if (reader.getName().equals("author")) {
					author = readAuthor(reader);
				} else if (reader.getName().equals("category")) {
					categories = readCategory(reader, categories);
				} else if (reader.getName().equals("creator")) {
					System.out.println(" creator-->" + reader.nextText());
				} else if (reader.getName().equals("comments")) {
					comments = readComments(reader);
				} else if (reader.getName().equals("enclosure")) {
					enclosure = readEnclosure(reader);
				} else if (reader.getName().equals("guid")) {
					guid = readGUID(reader);
				} else if (reader.getName().equals("pubDate")) {
					pubDate = readPubDate(reader);
				} else if (reader.getName().equals("source")) {
					source = readSource(reader);
				} else {
					// extension
					try {
						extensions = readExtension(reader, extensions,
								reader.getName());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				break;
			case XmlPullParser.END_TAG:
				if (reader.getName().equals("item")) {
					return AndroidRSSDoc.buildItem(title, link, description,
							author, categories, comments, enclosure, guid,
							pubDate, source, extensions);
				}
				break;
			}
		}
		return null;
	}

	@Override
	protected Image readImage(XmlPullParser reader) throws Exception {
		URL url = null;
		Title title = null;
		Link link = null;
		Width width = null;
		Height height = null;
		Description description = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("url")) {
					url = readURL(reader);
				} else if (reader.getName().equals("title")) {
					title = readTitle(reader);
				} else if (reader.getName().equals("link")) {
					link = readLink(reader);
				} else if (reader.getName().equals("width")) {
					width = readWidth(reader);
				} else if (reader.getName().equals("height")) {
					height = readHeight(reader);
				} else if (reader.getName().equals("description")) {
					description = readDescription(reader);
				}
				break;
			case XmlPullParser.END_TAG:
				if (reader.getName().equals("image")) {
					return AndroidRSSDoc.buildImage(url, title, link, width,
							height, description);
				}
				break;
			}
		}
		return null;
	}

	@Override
	protected TextInput readTextInput(XmlPullParser reader) throws Exception {
		Title title = null;
		Description description = null;
		Name name = null;
		Link link = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("title")) {
					title = readTitle(reader);
				} else if (reader.getName().equals("description")) {
					description = readDescription(reader);
				} else if (reader.getName().equals("name")) {
					name = readName(reader);
				} else if (reader.getName().equals("link")) {
					link = readLink(reader);
				}
				break;
			case XmlPullParser.END_TAG:
				if (reader.getName().equals("textInput")) {
					return AndroidRSSDoc.buildTextInput(title, description,
							name, link);
				}
				break;
			}
		}
		return null;
	}

	@Override
	protected String readEncodedHTML(XmlPullParser reader, String parentElement)
			throws Exception {
		StringBuilder xhtml = new StringBuilder();
		boolean breakOut = false;

		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				;
				xhtml.append("&lt;" + reader.getName());
				List<Attribute> attributes = getAttributes(reader);
				// add the attributes
				if (attributes != null && attributes.size() > 0) {
					for (Attribute attr : attributes) {
						xhtml.append(" "
								+ attr.getName()
								+ "=\""
								+ attr.getValue().replaceAll("&amp;", "&")
										.replaceAll("&", "&amp;") + "\"");
					}
				}
				xhtml.append("&gt;");
				break;

			case XmlPullParser.END_TAG:
				if (reader.getName().equals(parentElement)) {
					breakOut = true;
				} else {
					xhtml.append("&lt;/" + reader.getName() + "&gt;");
				}
				break;

			default:
				xhtml.append(reader.getText().replaceAll("&", "&amp;")
						.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
			}
			if (breakOut) {
				break;
			}
		}
		return xhtml.toString();
	}

	@Override
	protected List<Attribute> getAttributes(XmlPullParser reader)
			throws Exception {
		// TODO Auto-generated method stub
		List<Attribute> attributes = new LinkedList<Attribute>();
		if (reader.getEventType() == XmlPullParser.START_DOCUMENT) {
			System.out.println(reader.getInputEncoding());
			System.out.println("1.0");
		}
		// List<AndroidRSSDoc.ProcessingInstruction> processingInstructions =
		// null;
		// while (reader.getEventType() != XMLStreamConstants.START_ELEMENT
		// && reader.getEventType() != XMLStreamConstants.END_ELEMENT
		// && reader.getEventType() != XMLStreamConstants.NAMESPACE) {
		// if (reader.getEventType() ==
		// XMLStreamConstants.PROCESSING_INSTRUCTION) {
		// if (processingInstructions == null) {
		// processingInstructions = new
		// LinkedList<AndroidRSSDoc.ProcessingInstruction>();
		// }
		// processingInstructions
		// .add(new AndroidRSSDoc().new ProcessingInstruction(reader
		// .getPITarget(), reader.getPIData()));
		// }
		// reader.next();
		// }
		//
		// if (processingInstructions != null) {
		// rss.setProcessingInstructions(processingInstructions);
		// }
		//
		for (int i = 0; i < reader.getNamespaceCount(reader.getDepth()); i++) {
			String attrName = "xmlns";
			if (reader.getNamespacePrefix(i) != null) {
				attrName += ":" + reader.getNamespacePrefix(i);
			}
			attributes.add(AndroidRSSDoc.buildAttribute(attrName,
					reader.getNamespaceUri(i).replaceAll("&amp;", "&")
							.replaceAll("&", "&amp;")));
		}

		for (int i = 0; i < reader.getAttributeCount(); i++) {
			String attrName = null;
			if (reader.getPrefix() != null && !reader.getPrefix().equals("")) {
				attrName = reader.getPrefix() + ":"
						+ reader.getAttributeName(i);
			} else {
				attrName = reader.getAttributeName(i);
			}
			attributes.add(AndroidRSSDoc.buildAttribute(attrName,
					reader.getAttributeValue(i).replaceAll("&amp;", "&")
							.replaceAll("&", "&amp;")));
		}

		return (attributes.size() == 0) ? null : attributes;
	}

	@Override
	protected List<Extension> readExtension(XmlPullParser reader,
			List<Extension> extensions, String elementName) throws Exception {
		if (extensions == null) {
			extensions = new LinkedList<Extension>();
		}

		StringBuilder extText = new StringBuilder();
		List<Attribute> attributes = getAttributes(reader);

		if (containsXHTML(reader, elementName)) {
			extText.append(readXHTML(reader, elementName));
		} else {
			for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
					.next()) {
				switch (eventType) {
				case XmlPullParser.START_TAG:
					if (!reader.getName().equals(elementName)) {
						extText.append(readSubExtension(reader,
								reader.getName(), attributes));
					}
					break;
				case XmlPullParser.END_TAG:
					if (reader.getName().equals(elementName)) {
						extensions.add(AndroidRSSDoc.buildExtension(
								elementName, attributes, extText.toString()));
						return extensions;
					}
					break;
				default:
					extText.append(reader.getText());
					break;
				}
			}
		}
		return null;
	}

	@Override
	protected SkipDays readSkipDays(XmlPullParser reader) throws Exception {
		List<Day> days = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (reader.getName().equals("day")) {
					days = readDay(reader, days);
				}
				break;

			case XmlPullParser.END_TAG:
				if (reader.getName().equals("skipDays")) {
					return AndroidRSSDoc.buildSkipDays(days);
				}
				break;
			}
		}
		return null;

	}

	@Override
	protected List<Day> readDay(XmlPullParser reader, List<Day> days)
			throws Exception {
		if (days == null) {
			days = new LinkedList<Day>();
		}
		days.add(AndroidRSSDoc.buildDay(reader.nextText()));
		return days;
	}

	@Override
	protected SkipHours readSkipHours(XmlPullParser reader) throws Exception {
		List<Hour> hours = null;
		for (int eventType; (eventType = reader.getEventType()) != XmlPullParser.END_DOCUMENT; reader
				.next()) {
			switch (eventType) {

			case XmlPullParser.START_TAG:
				if (reader.getName().equals("hour")) {
					hours = readHour(reader, hours);
				}
				break;

			case XmlPullParser.END_TAG:
				if (reader.getName().equals("skipHours")) {
					return AndroidRSSDoc.buildSkipHours(hours);
				}
				break;
			}
		}
		return null;
	}

	@Override
	protected List<Hour> readHour(XmlPullParser reader, List<Hour> hours)
			throws Exception {
		if (hours == null) {
			hours = new LinkedList<Hour>();
		}
		hours.add(AndroidRSSDoc.buildHour(reader.nextText()));
		return hours;
	}

	@Override
	protected LastBuildDate readLastBuildDate(XmlPullParser reader)
			throws Exception {
		// System.out.println("LastBuildDate --->" + reader.nextText());
		return AndroidRSSDoc.buildLastBuildDate(reader.nextText());
		// return null;
	}

	@Override
	protected PubDate readPubDate(XmlPullParser reader) throws Exception {
		// return AndroidRSSDoc.buildPubDate(reader.nextText());
		return null;
	}

	@Override
	protected Name readName(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildName(reader.nextText());
	}

	@Override
	protected List<Category> readCategory(XmlPullParser reader,
			List<Category> categories) throws Exception {
		if (categories == null) {
			categories = new LinkedList<Category>();
		}
		categories.add(AndroidRSSDoc.buildCategory(
				getAttributeFromGroup(getAttributes(reader), "domain"),
				reader.nextText()));
		return categories;
	}

	@Override
	protected Width readWidth(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildWidth(reader.nextText());
	}

	@Override
	protected URL readURL(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildURL(reader.nextText());
	}

	@Override
	protected Source readSource(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildSource(
				getAttributeFromGroup(getAttributes(reader), "url"),
				reader.nextText());
	}

	@Override
	protected Title readTitle(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildTitle(reader.nextText());
	}

	@Override
	protected Language readLanguage(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildLanguage(reader.nextText());
	}

	@Override
	protected Rating readRating(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildRating(reader.nextText());
	}

	@Override
	protected TTL readTTL(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildTTL(reader.nextText());
	}

	@Override
	protected WebMaster readWebMaster(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildWebMaster(reader.nextText());
	}

	@Override
	protected ManagingEditor readManagingEditor(XmlPullParser reader)
			throws Exception {
		return AndroidRSSDoc.buildManagingEditor(reader.nextText());
	}

	@Override
	protected Cloud readCloud(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildCloud(getAttributes(reader));
	}

	@Override
	protected Comments readComments(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildComments(reader.nextText());
	}

	@Override
	protected Copyright readCopyright(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildCopyright(reader.nextText());
	}

	@Override
	protected Description readDescription(XmlPullParser reader)
			throws Exception {
		// return AndroidRSSDoc.buildDescription(readEncodedHTML(reader,
		// "description"));
		return AndroidRSSDoc.buildDescription(reader.nextText());
	}

	@Override
	protected Docs readDocs(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildDocs(reader.nextText());
	}

	@Override
	protected Enclosure readEnclosure(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildEnclosure(getAttributes(reader));
	}

	@Override
	protected Generator readGenerator(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildGenerator(reader.nextText());
	}

	@Override
	protected GUID readGUID(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildGUID(
				getAttributeFromGroup(getAttributes(reader), "isPermaLink"),
				reader.nextText());
	}

	@Override
	protected Link readLink(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildLink(reader.nextText());
	}

	@Override
	protected Height readHeight(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildHeight(reader.nextText());
	}

	@Override
	protected Author readAuthor(XmlPullParser reader) throws Exception {
		return AndroidRSSDoc.buildAuthor(reader.nextText());
	}
}
